package com.sc.nft.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.entity.DaoCustomerOpenAccount;
import com.sc.nft.entity.DaoTransfer;
import com.sc.nft.entity.DaoWallet;
import com.sc.nft.entity.UserCreatorInfo;
import com.sc.nft.entity.vo.DaoTransferDetailVO;
import com.sc.nft.enums.*;
import com.sc.nft.enums.wallet.DaoTransferTypeEnum;
import com.sc.nft.enums.wallet.DaoWalletTypeEnum;
import com.sc.nft.enums.wallet.MallDaoWalletTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.helper.LlPayHelper;
import com.sc.nft.service.DaoWalletService;
import com.sc.nft.service.MallDaoWalletService;
import com.sc.nft.service.UserWalletService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.service.DaoTransferService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 企业转账表服务接口实现
 *
 * @author zxy
 * @since 2023-12-21 15:18:22
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DaoTransferServiceImpl implements DaoTransferService {
    private final DaoTransferDao daoTransferDao;
    private final DaoWalletDao daoWalletDao;
    private final DaoWalletService daoWalletService;
    private final MallDaoWalletService mallDaoWalletService;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final UserWalletService userWalletService;
    private final UserWalletDao userWalletDao;
    private final DaoCustomerOpenAccountDao daoCustomerOpenAccountDao;
    private final FilterIncomeListDao filterIncomeListDao;
    private final LlPayHelper llPayHelper;
    private final MallDaoWalletDao mallDaoWalletDao;

    @Override
    public Page<DaoTransferDetailVO> getRecords(Long daoId,Integer scence, DaoTransferTypeEnum type, String applyTel, String marketAccount, WalletChannelEnum walletChannel, ApprovalStatusEnum status, Date startTime, Date endTime,Page page) {
        Page<DaoTransferDetailVO> records = daoTransferDao.getRecords(daoId, scence, type, applyTel, marketAccount, walletChannel, status, startTime, endTime, page);
        for (DaoTransferDetailVO record : records.getRecords()) {
            switch (record.getType()) {
                case TRANSFER:
                    record.setMarketAccount("--");
                    break;
                case MALL_TRANSFER:
                    record.setMarketAccount("--");
                    break;
            }
            record.setTypeTxt(record.getType().getDescription());
        }
        return records;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approval(Long id, Boolean status, String remark) {
        DaoTransfer transfer = daoTransferDao.getById(id);
        Assert.notNull(transfer,()->new GlobalRunTimeException("未找到转账记录"));
        Assert.isTrue(transfer.getStatus()==ApprovalStatusEnum.APPROVAL,()->new GlobalRunTimeException("转账记录状态不是审批中"));
        if(status){
            transfer.setStatus(ApprovalStatusEnum.PASS);
            transfer.updateById();
            switch (transfer.getType()) {
                case TRANSFER:
                    daoWalletDao.pass(transfer.getDaoId(),transfer.getAmount());
                    switch (transfer.getWalletChannel()) {
                        case LL:
                            UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(transfer.getDaoId());
                            llPayHelper.daoTransfer(userCreatorInfo,transfer);
                            break;
                        default:
                            throw new GlobalRunTimeException("暂不支持该渠道转账");
                    }
                    break;
                case MARKET_VALUE_IN:
                    daoWalletService.addBalance(transfer.getDaoId(),transfer.getSourceId(),transfer.getAmount(),BigDecimal.ZERO, DaoWalletTypeEnum.MARKET_IN,DaoWalletTypeEnum.MARKET_IN.getDescription());
                    userWalletDao.transferSuccess(transfer.getSourceId(),transfer.getAmount());
                    break;
                case MARKET_VALUE_OUT:
                    daoWalletDao.pass(transfer.getDaoId(),transfer.getAmount());
                    userWalletService.addIncome(transfer.getSourceId(),null,transfer.getAmount(), BigDecimal.ZERO, WalletDetailTypeEnum.DAO_TRANSFER_IN, ExpenditureRecordTypeEnum.BACKSTAGE_ADD,"DAO转入");
                    break;
                case MALL_TRANSFER:
                    mallDaoWalletDao.pass(transfer.getDaoId(),transfer.getAmount());
                    switch (transfer.getWalletChannel()) {
                        case LL:
                            UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(transfer.getDaoId());
                            llPayHelper.daoTransfer(userCreatorInfo,transfer);
                            break;
                        default:
                            throw new GlobalRunTimeException("暂不支持该渠道转账");
                    }
                    break;
            }

        }else {
            transfer.setStatus(ApprovalStatusEnum.REFUSE);
            transfer.setRemark(remark);
            transfer.updateById();
            switch (transfer.getType()) {
                case TRANSFER:
                    daoWalletService.refuse(transfer.getDaoId(),transfer.getId(),transfer.getAmount());
                    break;
                case MARKET_VALUE_IN:
                    userWalletService.transferFail(transfer.getSourceId(),transfer.getAmount());
                    break;
                case MARKET_VALUE_OUT:
                    daoWalletService.refuse(transfer.getDaoId(),transfer.getId(),transfer.getAmount());
                    break;
                case MALL_TRANSFER:
                    mallDaoWalletService.refuse(transfer.getDaoId(),transfer.getAmount());
                    break;
            }
        }


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revoke(Long id, Long daoId, Long operatorId) {
        DaoTransfer daoTransfer = daoTransferDao.getById(id);
        Assert.isTrue(ObjectUtil.isNotNull(daoTransfer)&&daoTransfer.getDaoId().longValue()==daoId.longValue(),()->new GlobalRunTimeException("未找到转账记录"));
        Assert.isTrue(daoTransfer.getStatus()==ApprovalStatusEnum.APPROVAL,()->new GlobalRunTimeException("该记录状态不是审核中，不能撤销"));
        switch (daoTransfer.getType()) {
            case TRANSFER:
                daoWalletService.refuse(daoTransfer.getDaoId(),daoTransfer.getId(),daoTransfer.getAmount());
                break;
            case MARKET_VALUE_IN:
                userWalletService.transferFail(daoTransfer.getSourceId(),daoTransfer.getAmount());
                break;
            case MARKET_VALUE_OUT:
                daoWalletService.refuse(daoTransfer.getDaoId(),daoTransfer.getId(),daoTransfer.getAmount());
                break;
            case MALL_TRANSFER:
                mallDaoWalletService.refuse(daoTransfer.getDaoId(),daoTransfer.getAmount());
                break;
        }
        daoTransfer.setStatus(ApprovalStatusEnum.REVOKE);
        daoTransfer.updateById();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void daoApplyToThird(Long id,Long daoId,  Long operatorId,  BigDecimal amount) {
        DaoCustomerOpenAccount account = daoCustomerOpenAccountDao.getById(id);
        Assert.notNull(account ,()->new GlobalRunTimeException("未完成三方开户,无法转账"));
        Assert.isTrue(account.getDaoId().longValue()==daoId.longValue() ,()->new GlobalRunTimeException("未完成三方开户,无法转账"));
        Assert.isTrue( account.getStatus()== AccountStatusEnum.SUCCESS,()->new GlobalRunTimeException("未完成三方开户,无法转账"));
        daoWalletService.freezeBalance(daoId,account.getId(),amount,BigDecimal.ZERO,DaoWalletTypeEnum.TRANSFER_WALLET,DaoWalletTypeEnum.TRANSFER_WALLET.getDescription());
        DaoTransfer daoTransfer = new DaoTransfer();
        daoTransfer.setDaoId(daoId);
        daoTransfer.setType(DaoTransferTypeEnum.TRANSFER);
        daoTransfer.setWalletChannel(account.getChannel());
        daoTransfer.setTradeNo(UUID.randomUUID().toString(true));
        daoTransfer.setSourceId(account.getId());
        daoTransfer.setApplyTime(DateTime.now());
        daoTransfer.setApplyId(operatorId);
        daoTransfer.setAmount(amount);
        daoTransfer.setStatus(ApprovalStatusEnum.APPROVAL);
        daoTransfer.insert();
    }

    @Override
    public void mallDaoApplyToThird(Long id, Long daoId, Long operatorId, BigDecimal amount) {
        DaoCustomerOpenAccount account = daoCustomerOpenAccountDao.getById(id);
        Assert.notNull(account ,()->new GlobalRunTimeException("未完成三方开户,无法转账"));
        Assert.isTrue(account.getDaoId().longValue()==daoId.longValue() ,()->new GlobalRunTimeException("未完成三方开户,无法转账"));
        Assert.isTrue( account.getStatus()== AccountStatusEnum.SUCCESS,()->new GlobalRunTimeException("未完成三方开户,无法转账"));
        mallDaoWalletService.freezeBalance(daoId,amount,BigDecimal.ZERO, MallDaoWalletTypeEnum.TRANSFER_WALLET,MallDaoWalletTypeEnum.TRANSFER_WALLET.getDescription());
        DaoTransfer daoTransfer = new DaoTransfer();
        daoTransfer.setDaoId(daoId);
        daoTransfer.setType(DaoTransferTypeEnum.MALL_TRANSFER);
        daoTransfer.setWalletChannel(account.getChannel());
        daoTransfer.setTradeNo(UUID.randomUUID().toString(true));
        daoTransfer.setSourceId(account.getId());
        daoTransfer.setApplyTime(DateTime.now());
        daoTransfer.setApplyId(operatorId);
        daoTransfer.setAmount(amount);
        daoTransfer.setStatus(ApprovalStatusEnum.APPROVAL);
        daoTransfer.insert();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void daoApplyToMarket(Long marketAccountId, Long daoId, Long operatorId, BigDecimal amount) {
        Assert.isTrue(filterIncomeListDao.checkIsFilterAccount(daoId, marketAccountId),()->new GlobalRunTimeException("未找到对应的市值账号"));
        daoWalletService.freezeBalance(daoId,marketAccountId,amount,BigDecimal.ZERO,DaoWalletTypeEnum.MARKET_OUT,DaoWalletTypeEnum.MARKET_OUT.getDescription());
        DaoTransfer daoTransfer = new DaoTransfer();
        daoTransfer.setDaoId(daoId);
        daoTransfer.setType(DaoTransferTypeEnum.MARKET_VALUE_OUT);
        daoTransfer.setWalletChannel(WalletChannelEnum.LL);
        daoTransfer.setTradeNo(UUID.randomUUID().toString(true));
        daoTransfer.setSourceId(marketAccountId);
        daoTransfer.setApplyTime(DateTime.now());
        daoTransfer.setApplyId(operatorId);
        daoTransfer.setAmount(amount);
        daoTransfer.setStatus(ApprovalStatusEnum.APPROVAL);
        daoTransfer.insert();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void marketApplyToDao(Long marketAccountId, Long daoId, Long operatorId, BigDecimal amount) {
        Assert.isTrue(filterIncomeListDao.checkIsFilterAccount(daoId, marketAccountId),()->new GlobalRunTimeException("未找到对应的dao组织"));
        userWalletService.transfer(marketAccountId,amount,WalletDetailTypeEnum.TRANSFER_TO_DAO,ExpenditureRecordTypeEnum.TRANSFER_DAO);
        DaoTransfer daoTransfer = new DaoTransfer();
        daoTransfer.setDaoId(daoId);
        daoTransfer.setType(DaoTransferTypeEnum.MARKET_VALUE_IN);
        daoTransfer.setWalletChannel(WalletChannelEnum.LL);
        daoTransfer.setTradeNo(UUID.randomUUID().toString(true));
        daoTransfer.setSourceId(marketAccountId);
        daoTransfer.setApplyTime(DateTime.now());
        daoTransfer.setApplyId(operatorId);
        daoTransfer.setAmount(amount);
        daoTransfer.setStatus(ApprovalStatusEnum.APPROVAL);
        daoTransfer.insert();
    }
}